package modules.fin.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import luxing.common.controller.BaseController;
import luxing.exception.BusinessException;
import luxing.hibernate.CriteriaQuery;
import luxing.util.CriteriaQueryUtil;
import luxing.util.ValidatorUtil;
import luxing.web.model.DataGrid;
import luxing.web.model.Result;
import modules.arc.entity.Vehicle;
import modules.fin.entity.Expenses;
import modules.fin.entity.Income;
import modules.fin.entity.IncomeSum;
import modules.fin.service.ExpensesService;
import modules.fin.service.IncomeService;
import modules.sys.entity.Log;
import modules.sys.service.LogService;

/**
 * 
 * @author zzc
 *
 */
@Controller
@RequestMapping("/incomeController")
public class IncomeController extends BaseController {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(IncomeController.class);

	@Autowired
	private LogService logService;
	@Autowired
	private IncomeService incomeService;
	@Autowired
	private ExpensesService expensesService;

	/**
	 * 列表页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "index")
	public ModelAndView index(HttpServletRequest request) {
		List<Expenses> expensesList = expensesService.listByTypeAndStatus(Expenses.TYPE_INCOME,
				Expenses.STATUS_ENABLE);
		request.setAttribute("expensesList", expensesList);
		return new ModelAndView("modules/fin/income-list");
	}

	/**
	 * 列表数据
	 * 
	 * @param income
	 * @param request
	 * @param response
	 * @param dataGrid
	 */
	@RequestMapping(params = "list")
	public void list(Income income, HttpServletRequest request, HttpServletResponse response, DataGrid dataGrid) {
		try {
			CriteriaQuery cq = new CriteriaQuery(Income.class, dataGrid);
			CriteriaQueryUtil.assembling(cq, income, request.getParameterMap());
			// 费用类型
			String exs = request.getParameter("exs");
			if (StringUtils.isNotBlank(exs)) {
				cq.eq("expenses.id", exs);
			}
			cq.add();
			incomeService.listByPage(cq, true);
			dataGrid.setFooter("incomeAmount,discountAmount,settleAmount,vehicle.sn:合计");
			listView(response, dataGrid);
		} catch (Exception e) {
			logger.error("收车辆款查询失败", e);
			throw new BusinessException("收车辆款查询失败", e);
		}
	}

	/**
	 * 增加页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goAdd")
	public ModelAndView goAdd(HttpServletRequest req) {
		List<Expenses> expensesList = expensesService.listByTypeAndStatus(Expenses.TYPE_INCOME,
				Expenses.STATUS_ENABLE);
		if (CollectionUtils.isNotEmpty(expensesList)) {
			req.setAttribute("incomeAmount", expensesList.get(0).getAmount());
		}
		req.setAttribute("expensesList", expensesList);
		return new ModelAndView("modules/fin/income-add");
	}

	/**
	 * 修改页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goUpdate")
	public ModelAndView goUpdate(Income income, HttpServletRequest req) {
		if (StringUtils.isNotBlank(income.getId())) {
			income = incomeService.get(Income.class, income.getId());
			req.setAttribute("incomePage", income);
		}
		List<Expenses> expensesList = expensesService.listByTypeAndStatus(Expenses.TYPE_INCOME,
				Expenses.STATUS_ENABLE);
		req.setAttribute("expensesList", expensesList);
		return new ModelAndView("modules/fin/income-update");
	}

	/**
	 * 责任人核销页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goOwnerSettle")
	public ModelAndView goOwnerSettle(HttpServletRequest req) {
		return new ModelAndView("modules/fin/incomeOwner-settle");
	}

	/**
	 * 车辆核销页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goVehicleSettle")
	public ModelAndView goVehicleSettle(Income income, HttpServletRequest req) {
		if (StringUtils.isNotBlank(income.getId())) {
			income = incomeService.get(Income.class, income.getId());
			req.setAttribute("incomePage", income);
		}
		return new ModelAndView("modules/fin/incomeVehicle-settle");
	}

	/**
	 * 查看页面
	 * 
	 * @param insurance
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "goDetail")
	public ModelAndView goDetail(Income income, HttpServletRequest request) {
		if (StringUtils.isNotBlank(income.getId())) {
			income = incomeService.get(Income.class, income.getId());
			request.setAttribute("incomePage", income);
		}
		List<Expenses> expensesList = expensesService.listByTypeAndStatus(Expenses.TYPE_INCOME,
				Expenses.STATUS_ENABLE);
		request.setAttribute("expensesList", expensesList);
		return new ModelAndView("modules/fin/income-detail");
	}

	/**
	 * 费用tab
	 * 
	 * @return
	 */
	@RequestMapping(params = "expensesTab")
	public ModelAndView expensesList(HttpServletRequest req) {
		List<Expenses> expensesList = expensesService.listByTypeAndStatus(Expenses.TYPE_INCOME,
				Expenses.STATUS_ENABLE);
		if (CollectionUtils.isNotEmpty(expensesList)) {
			req.setAttribute("incomeAmount", expensesList.get(0).getAmount());
		}
		req.setAttribute("expensesList", expensesList);
		return new ModelAndView("modules/fin/incomeExpenses-tab");
	}

	/**
	 * 责任人核销明细
	 * 
	 * @return
	 */
	@RequestMapping(params = "ownerSettleTab")
	public ModelAndView ownerSettleTab(HttpServletRequest req) {
		String ownerId = req.getParameter("ownerId");
		List<Income> incomeList = incomeService.listByOwnerAndStatus(ownerId, Income.STATUS_NO);
		BigDecimal totalIncomeAmount = new BigDecimal(0);
		BigDecimal totalDiscountAmount = new BigDecimal(0);
		BigDecimal totalSettleAmount = new BigDecimal(0);
		for (Income income : incomeList) {
			totalIncomeAmount = totalIncomeAmount.add(income.getIncomeAmount());
			totalSettleAmount = totalIncomeAmount;
		}
		req.setAttribute("totalIncomeAmount", totalIncomeAmount);
		req.setAttribute("totalDiscountAmount", totalDiscountAmount);
		req.setAttribute("totalSettleAmount", totalSettleAmount);
		req.setAttribute("incomeList", incomeList);
		return new ModelAndView("modules/fin/incomeOwnerSettle-tab");
	}

	/**
	 * 车辆核销明细
	 * 
	 * @return
	 */
	@RequestMapping(params = "vehicleSettleTab")
	public ModelAndView vehicleSettleTab(HttpServletRequest req) {
		String vehicleId = req.getParameter("vehicleId");
		List<Income> incomeList = incomeService.listByVehicleAndStatus(vehicleId, Income.STATUS_NO);
		BigDecimal totalIncomeAmount = new BigDecimal(0);
		BigDecimal totalDiscountAmount = new BigDecimal(0);
		BigDecimal totalSettleAmount = new BigDecimal(0);
		for (Income income : incomeList) {
			totalIncomeAmount = totalIncomeAmount.add(income.getIncomeAmount());
			totalSettleAmount = totalIncomeAmount;
		}
		req.setAttribute("totalIncomeAmount", totalIncomeAmount);
		req.setAttribute("totalDiscountAmount", totalDiscountAmount);
		req.setAttribute("totalSettleAmount", totalSettleAmount);
		req.setAttribute("incomeList", incomeList);
		return new ModelAndView("modules/fin/incomeVehicleSettle-tab");
	}

	/**
	 * 新增
	 * 
	 * @param income
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doAdd")
	@ResponseBody
	public Result doAdd(Income income, HttpServletRequest request) {
		String msg = null;
		try {
			String vehicleId = request.getParameter("vehicleId");
			if (CollectionUtils.isNotEmpty(income.getIncomeList())) {
				List<Income> incomeList = new ArrayList<Income>();
				for (Income entity : income.getIncomeList()) {
					for (String id : vehicleId.split(",")) {
						Income incomeEntity = new Income();
						incomeEntity.setExpenses(entity.getExpenses());
						incomeEntity.setIncomeAmount(entity.getIncomeAmount());
						incomeEntity.setEndDate(entity.getEndDate());
						incomeEntity.setStatus(Income.STATUS_NO);
						Vehicle vehicle = new Vehicle();
						vehicle.setId(id);
						incomeEntity.setVehicle(vehicle);
						incomeEntity.setDiscountAmount(new BigDecimal(0));
						incomeEntity.setSettleAmount(new BigDecimal(0));
						incomeEntity.setRemarks(entity.getRemarks());
						incomeList.add(incomeEntity);
					}
				}
				incomeService.save(incomeList);
			}
			msg = "收款登记成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_ADD);
		} catch (Exception e) {
			msg = "收款登记失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 核销
	 * 
	 * @param incomeSum
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doSettle")
	@ResponseBody
	public Result doSettle(IncomeSum incomeSum, HttpServletRequest request) {
		String msg = null;
		try {
			if (CollectionUtils.isNotEmpty(incomeSum.getIncomeList())) {
				// 编号
				String sn = incomeService.getSn();
				incomeSum.setSn(sn);
				// 状态
				incomeSum.setStatus(IncomeSum.STATUS_ENABLE);
				// 核销金额
				BigDecimal totalSettleAmount = new BigDecimal(0);
				Iterator<Income> iterator = incomeSum.getIncomeList().iterator();
				while (iterator.hasNext()) {
					Income income = iterator.next();
					if (StringUtils.equals(income.getStatus(), Income.STATUS_YES) && income.getDiscountAmount()
							.add(income.getSettleAmount()).compareTo(income.getIncomeAmount()) == 0) {
						totalSettleAmount = totalSettleAmount.add(income.getSettleAmount());
					} else {
						iterator.remove();
					}
				}
				incomeSum.setAmount(totalSettleAmount);
				// bean校验
				msg = ValidatorUtil.validate(incomeSum);
				if (StringUtils.isNotBlank(msg)) {
					return Result.error(msg);
				}
				incomeService.settle(incomeSum);
				msg = "责任人\"" + incomeSum.getOwner().getName() + "\"收款核销成功";
				logger.info(msg);
				logService.addLogInfo(msg, Log.OPERATE_ADD);
			}
		} catch (Exception e) {
			msg = "责任人\"" + incomeSum.getOwner().getName() + "\"收款核销失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 修改
	 * 
	 * @param income
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doUpdate")
	@ResponseBody
	public Result doUpdate(Income income, HttpServletRequest request) {
		String msg = null;
		try {
			incomeService.saveOrUpdate(income);
			msg = "车辆\"" + income.getVehicle().getPlateNumber() + "\"收款修改成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_UPDATE);
		} catch (Exception e) {
			msg = "车辆\"" + income.getVehicle().getPlateNumber() + "\"收款修改失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 删除
	 * 
	 * @return
	 */
	@RequestMapping(params = "doDel")
	@ResponseBody
	public Result doDel(Income income, HttpServletRequest request) {
		String msg = null;
		try {
			income = incomeService.get(Income.class, income.getId());
			incomeService.delete(income);
			msg = "车辆\"" + income.getVehicle().getPlateNumber() + "\"收款删除成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_DEL);
		} catch (Exception e) {
			msg = "车辆\"" + income.getVehicle().getPlateNumber() + "\"收款删除失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 费用change
	 * 
	 * @param req
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(params = "expensesChange")
	@ResponseBody
	public Result expensesChange(HttpServletRequest req) {
		Result result = new Result();
		Map<String, Object> attributes = new HashMap<String, Object>();
		String expensesId = req.getParameter("expensesId");
		Expenses expenses = expensesService.get(Expenses.class, expensesId);
		attributes.put("incomeAmount", expenses.getAmount());
		result.setAttributes(attributes);
		return result;
	}

	/**
	 * 优惠金额 change
	 * 
	 * @param req
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(params = "discountAmountChange")
	@ResponseBody
	public Result discountAmountChange(HttpServletRequest req) {
		Result result = new Result();
		Map<String, Object> attributes = new HashMap<String, Object>();
		String incomeAmount = req.getParameter("incomeAmount");
		String discountAmount = req.getParameter("discountAmount");
		BigDecimal settleAmount = BigDecimal.valueOf(Double.valueOf(incomeAmount))
				.subtract(BigDecimal.valueOf(Double.valueOf(discountAmount)));
		attributes.put("settleAmount", settleAmount);
		result.setAttributes(attributes);
		return result;
	}

	/**
	 * 核销金额 change
	 * 
	 * @param req
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(params = "settleAmountChange")
	@ResponseBody
	public Result settleAmountChange(HttpServletRequest req) {
		Result result = new Result();
		Map<String, Object> attributes = new HashMap<String, Object>();
		String incomeAmount = req.getParameter("incomeAmount");
		String settleAmount = req.getParameter("settleAmount");
		BigDecimal discountAmount = BigDecimal.valueOf(Double.valueOf(incomeAmount))
				.subtract(BigDecimal.valueOf(Double.valueOf(settleAmount)));
		attributes.put("discountAmount", discountAmount);
		result.setAttributes(attributes);
		return result;
	}

}
